package com.mmd.common.utils;

import com.mmd.utils.DateUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ExcelUtil {

    private static Logger logger = LoggerFactory.getLogger(ExcelUtil.class);

    public final static String FmtOfTime = "yyyyMMddHHmmss";

    public static void export(byte[] result, String fileName, HttpServletResponse response) throws Exception {
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName + DateUtil.date2String(new Date(), FmtOfTime) + ".xlsx", "UTF-8"));
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Length", "" + result.length);
        OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
        toClient.write(result);
        toClient.flush();
        toClient.close();
    }

    public static void export(byte[] result, String fileName, HttpServletResponse response, Object nullObject) throws Exception {
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Length", "" + result.length);
        OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
        toClient.write(result);
        toClient.flush();
        toClient.close();
    }

    public static void export(Workbook wb, String fileName, HttpServletResponse response) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        wb.write(out);
        byte[] result = out.toByteArray();
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName + DateUtil.date2String(new Date(), FmtOfTime) + ".xlsx", "UTF-8"));
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Length", "" + result.length);
        OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
        toClient.write(result);
        toClient.flush();
        toClient.close();
    }

    public static byte[] export(Workbook wb) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        wb.write(out);
        byte[] result = out.toByteArray();
        return result;
    }

    public static void export(Workbook wb, String fileName, HttpServletResponse response, Object nullObject) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        wb.write(out);
        byte[] result = out.toByteArray();
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Length", "" + result.length);
        OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
        toClient.write(result);
        toClient.flush();
        toClient.close();
    }

    public static void exportLocal(Workbook wb, String fileName, HttpServletResponse response, HttpServletRequest request) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        wb.write(out);
        byte[] result = out.toByteArray();
        String path = request.getSession().getServletContext().getRealPath("/");
        FileOutputStream fos = new FileOutputStream(new File(path + "/" + fileName + DateUtil.date2String(new Date(), FmtOfTime) + ".xlsx"));
        fos.write(result);
        fos.close();
    }

    public static void exportLocal(byte[] result, String fileName, HttpServletResponse response, HttpServletRequest request) throws Exception {
        String path = request.getSession().getServletContext().getRealPath("/");
        FileOutputStream fos = new FileOutputStream(new File(path + "/" + fileName + DateUtil.date2String(new Date(), FmtOfTime) + ".xlsx"));
        fos.write(result);
        fos.close();
    }

    public static byte[] exportByte(Workbook wb) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        wb.write(out);
        return out.toByteArray();
    }

    public static void exportZipFile(List<Workbook> wb, List<String> fileName, String zipFileName, HttpServletRequest request, HttpServletResponse response, boolean isFmtDate) throws IOException {
        OutputStream out = null;
        FileInputStream inStream = null;
        {
            try {
                out = response.getOutputStream();
                File zipFile = new File(zipFileName + ".zip");
                setResponseHeader(response, zipFileName);
                String path = request.getSession().getServletContext().getRealPath("/");
                File[] srcfile = new File[wb.size()];
                for (int i = 0; i < wb.size(); i++) {
                    File file = new File(path + "/" + fileName.get(i) + ".xlsx");
                    FileOutputStream o = new FileOutputStream(file);
                    srcfile[i] = file;
                    wb.get(i).write(o);
                    o.close();
                }
                ZipFiles(srcfile, zipFile);
                inStream = new FileInputStream(zipFile);
                byte[] buf = new byte[4096];
                int readLength;
                while (((readLength = inStream.read(buf)) != -1)) {
                    out.write(buf, 0, readLength);
                }
                inStream.close();
                for (File file : srcfile) {
                    deleteExcelPath(file);
                }
                deleteExcelPath(zipFile);
            } catch (Exception e1) {
                e1.printStackTrace();
            } finally {
                try {
                    if (null != out) {
                        out.flush();
                        out.close();
                    }
                    if (null != inStream) {
                        inStream.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void createZipFile(List<Workbook> wb, List<String> fileName, String zipFileName, String path) throws IOException {
        FileInputStream inStream = null;
        OutputStream out = null;
        {
            try {
                File zipFile = new File(path + "/" + zipFileName + ".zip");
                if (zipFile.exists()) {
                    zipFile.delete();
                }
                out = new FileOutputStream(zipFile);
                //String path = request.getSession().getServletContext().getRealPath("/");
                File[] srcfile = new File[wb.size()];
                for (int i = 0; i < wb.size(); i++) {
                    File file = new File(path + "/" + fileName.get(i) + ".xlsx");
                    FileOutputStream o = new FileOutputStream(file);
                    srcfile[i] = file;
                    wb.get(i).write(o);
                    o.close();
                }
                ZipFiles(srcfile, zipFile);
                inStream = new FileInputStream(zipFile);
                /*byte[] buf = new byte[4096];
                int readLength;
                while (((readLength = inStream.read(buf)) != -1)) {
                    out.write(buf, 0, readLength);
                }*/
                inStream.close();
                for (File file : srcfile) {
                    deleteExcelPath(file);
                }
                logger.info("生成文件成功:{}", path + "/" + zipFileName + ".zip");
            } catch (Exception e1) {
                logger.error("错误信息！", e1);
                e1.printStackTrace();
            } finally {
                try {
                    if (null != out) {
                        out.flush();
                        out.close();
                    }
                    if (null != inStream) {
                        inStream.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static byte[] createZipFile(List<Workbook> wb, List<String> fileName, String zipFileName) throws IOException {
        OutputStream out = null;
        {
            try {
                File zipFile = new File("/data/temp/" + zipFileName + ".zip");
                if (zipFile.exists()) {
                    zipFile.delete();
                }
                out = new FileOutputStream(zipFile);
                File[] srcfile = new File[wb.size()];
                for (int i = 0; i < wb.size(); i++) {
                    File file = new File("/data/temp/" + fileName.get(i) + ".xlsx");
                    FileOutputStream o = new FileOutputStream(file);
                    srcfile[i] = file;
                    wb.get(i).write(o);
                    o.close();
                }
                ZipFiles(srcfile, zipFile);
                for (File file : srcfile) {
                    deleteExcelPath(file);
                }
            } catch (Exception e1) {
                logger.error("错误信息！", e1);
            } finally {
                try {
                    if (null != out) {
                        out.flush();
                        out.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            FileInputStream fis = new FileInputStream("/data/temp/" + zipFileName + ".zip");
            int len;
            byte[] bs = new byte[1024];
            while ((len = fis.read(bs)) != -1) {
                bout.write(bs, 0, len);
            }
            return bout.toByteArray();
        }

    }

    public static void exportZipFileLocal(List<Workbook> wb, List<String> fileName, String zipFileName, HttpServletRequest request) throws IOException {
        File[] srcfile = new File[wb.size()];
        String path = request.getSession().getServletContext().getRealPath("/");
        for (int i = 0; i < wb.size(); i++) {
            File file = new File(path + "/" + fileName.get(i) + DateUtil.date2String(new Date(), FmtOfTime) + ".xlsx");
            FileOutputStream o = new FileOutputStream(file);
            srcfile[i] = file;
            wb.get(i).write(o);
            o.close();
        }
        File zipFile = new File(path + "/" + zipFileName + DateUtil.date2String(new Date(), FmtOfTime) + ".zip");
        ZipFiles(srcfile, zipFile);

        for (File file : srcfile) {
            deleteExcelPath(file);
        }
    }

    //压缩文件
    public static void ZipFiles(File[] srcfile, File zipfile) {
        byte[] buf = new byte[1024];
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(new FileOutputStream(
                    zipfile));
            for (int i = 0; i < srcfile.length; i++) {
                FileInputStream in = new FileInputStream(srcfile[i]);
                out.putNextEntry(new ZipEntry(srcfile[i].getName()));
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.closeEntry();
                in.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != out) {
                    out.flush();
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 设置响应头
     */
    public static void setResponseHeader(HttpServletResponse response, String fileName) {
        try {
            response.reset();// 清空输出流

            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".zip", "UTF-8"));
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static boolean deleteExcelPath(File file) {
        String[] files = null;
        if (file != null) {
            files = file.list();
        }
        if (file.isDirectory()) {
            for (int i = 0; i < files.length; i++) {
                boolean bol = deleteExcelPath(new File(file, files[i]));
                if (bol) {
                    System.out.println("删除成功!");
                } else {
                    System.out.println("删除失败!");
                }
            }
        }
        return file.delete();
    }

    public static void download(String url, String filename, HttpServletResponse response) {
        ByteArrayOutputStream out = null;
        try {
            InputStream in = new FileInputStream(url);
            XSSFWorkbook xWorkbook = new XSSFWorkbook(in);
            out = new ByteArrayOutputStream();
            xWorkbook.write(out);
            byte[] bytes = out.toByteArray();
            export(bytes, filename, response);
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void download(String path, String filename, HttpServletRequest request, HttpServletResponse response) {
        OutputStream out = null;
        try {
            try {
                response.reset();// 清空输出流
                response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
                response.setContentType("application/octet-stream;charset=UTF-8");
                response.addHeader("Pargam", "no-cache");
                response.addHeader("Cache-Control", "no-cache");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            out = response.getOutputStream();
            FileInputStream inStream = new FileInputStream(path + "/" + filename);
            byte[] buf = new byte[4096];
            int readLength;
            while (((readLength = inStream.read(buf)) != -1)) {
                out.write(buf, 0, readLength);
            }
            inStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static byte[] InputStream2ByteArray(String filePath) throws IOException {

        InputStream in = new FileInputStream(filePath);
        byte[] data = toByteArray(in);
        in.close();

        return data;
    }

    private static byte[] toByteArray(InputStream in) throws IOException {

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024 * 4];
        int n = 0;
        while ((n = in.read(buffer)) != -1) {
            out.write(buffer, 0, n);
        }
        return out.toByteArray();
    }
}

